<!DOCTYPE html>
<html lang="en"><head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1"><!-- Begin Jekyll SEO tag v2.8.0 -->
<title>0015: Entering and Leaving | gtkDcoding</title>
<meta name="generator" content="Jekyll v4.3.4" />
<meta property="og:title" content="0015: Entering and Leaving" />
<meta name="author" content="Ron Tarrant" />
<meta property="og:locale" content="en_US" />
<meta name="description" content="Tracking a mouse over and off a GTK widget - a D language tutorial." />
<meta property="og:description" content="Tracking a mouse over and off a GTK widget - a D language tutorial." />
<link rel="canonical" href="http://localhost:4000/posts/0015-enter-leave.html" />
<meta property="og:url" content="http://localhost:4000/posts/0015-enter-leave.html" />
<meta property="og:site_name" content="gtkDcoding" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2019-03-05T00:00:00-05:00" />
<meta name="twitter:card" content="summary" />
<meta property="twitter:title" content="0015: Entering and Leaving" />
<script type="application/ld+json">
{"@context":"https://schema.org","@type":"BlogPosting","author":{"@type":"Person","name":"Ron Tarrant"},"dateModified":"2019-03-05T00:00:00-05:00","datePublished":"2019-03-05T00:00:00-05:00","description":"Tracking a mouse over and off a GTK widget - a D language tutorial.","headline":"0015: Entering and Leaving","mainEntityOfPage":{"@type":"WebPage","@id":"http://localhost:4000/posts/0015-enter-leave.html"},"url":"http://localhost:4000/posts/0015-enter-leave.html"}</script>
<!-- End Jekyll SEO tag -->
<link rel="stylesheet" href="../assets/main.css">
  <link rel="stylesheet" href="../css/style.css" /><link type="application/atom+xml" rel="alternate" href="http://localhost:4000/feed.xml" title="gtkDcoding" /></head>
<body><header class="site-header" role="banner">

  <div class="wrapper"><a class="site-title" rel="author" href="../">gtkDcoding</a><nav class="site-nav">
        <input type="checkbox" id="nav-trigger" class="nav-trigger" />
        <label for="nav-trigger">
          <span class="menu-icon">
            <svg viewBox="0 0 18 15" width="18px" height="15px">
              <path d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.032C17.335,0,18,0.665,18,1.484L18,1.484z M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.032C17.335,6.031,18,6.696,18,7.516L18,7.516z M18,13.516C18,14.335,17.335,15,16.516,15H1.484 C0.665,15,0,14.335,0,13.516l0,0c0-0.82,0.665-1.483,1.484-1.483h15.032C17.335,12.031,18,12.695,18,13.516L18,13.516z"/>
            </svg>
          </span>
        </label>

        <div class="trigger"><a class="page-link" href="../about.html">About</a><a class="page-link" href="../index-reverse.html">Posts in Date Order</a><a class="page-link" href="../topics.html">Blog Posts by Topic</a></div>
      </nav></div>
</header>
<main class="page-content" aria-label="Content">
      <div class="wrapper">
        <article class="post h-entry" itemscope itemtype="http://schema.org/BlogPosting">
	<header class="post-header">
		<link rel="stylesheet" href="../css/font_size.css" />
		<link rel="stylesheet" href="../css/figure.css" />
		<link rel="stylesheet" href="../css/topics/mouse.css" />  <!-- sub in the tag/topic -->
		<link rel="stylesheet" href="../css/modal.css" />
		<link rel="stylesheet" href="../css/post.css" />
		<link rel="stylesheet" href="../css/mascot_effects.css" />

		
		
		<p class="post-meta">
		<time class="dt-published" datetime="2019-03-05T00:00:00-05:00" itemprop="datePublished">Tuesday, March 5, 2019
		</time>• by <span itemprop="author" itemscope itemtype="http://schema.org/Person"><span class="p-author h-card" itemprop="name">Ron Tarrant</span></span></p>
	</header>

	<div class="post-content e-content" itemprop="articleBody">
		<div class="skew-line"></div>
		<h1 id="0015-entering-and-leaving">0015: Entering and Leaving</h1>

<div class="screenshot-frame">
	<div class="frame-header">
		Results of this example:
	</div>
	<div class="frame-screenshot">
		<figure>
			<img id="img0" src="../images/screenshots/005_mouse/mouse_03.png" alt="Current example output" />		<!-- img# -->
			
			<!-- Modal for screenshot -->
			<div id="modal0" class="modal">																	<!-- modal# -->
				<span class="close0">&times;</span>															<!-- close# -->
				<img class="modal-content" id="img00" />															<!-- img## -->
				<div id="caption"></div>
			</div>
			
			<script>
			// Get the modal
			var modal = document.getElementById("modal0");														// modal#
			
			// Get the image and insert it inside the modal - use its "alt" text as a caption
			var img = document.getElementById("img0");															// img#
			var modalImg = document.getElementById("img00");													// img##
			var captionText = document.getElementById("caption");

			img.onclick = function()
			{
			  modal.style.display = "block";
			  modalImg.src = this.src;
			  captionText.innerHTML = this.alt;
			}
			
			// Get the <span> element that closes the modal
			var span = document.getElementsByClassName("close0")[0];											// close#
			
			// When the user clicks on <span> (x), close the modal
			span.onclick = function()
			{ 
				modal.style.display = "none";
			}
			</script>
			<figcaption>
			Current example output
			</figcaption>
		</figure>
	</div>

	<div class="frame-terminal">
		<figure class="right">
			<img id="img1" src="../images/screenshots/005_mouse/mouse_03_term.png" alt="Current example terminal output" />		<!-- img#, filename -->

			<!-- Modal for terminal shot -->
			<div id="modal1" class="modal">																				<!-- modal# -->
				<span class="close1">&times;</span>																		<!-- close# -->
				<img class="modal-content" id="img11" />																		<!-- img## -->
				<div id="caption"></div>
			</div>
			
			<script>
			// Get the modal
			var modal = document.getElementById("modal1");																	// modal#
			
			// Get the image and insert it inside the modal - use its "alt" text as a caption
			var img = document.getElementById("img1");																		// img#
			var modalImg = document.getElementById("img11");																// img##
			var captionText = document.getElementById("caption");

			img.onclick = function()
			{
			  modal.style.display = "block";
			  modalImg.src = this.src;
			  captionText.innerHTML = this.alt;
			}
			
			// Get the <span> element that closes the modal
			var span = document.getElementsByClassName("close1")[0];														// close#
			
			// When the user clicks on <span> (x), close the modal
			span.onclick = function()
			{ 
				modal.style.display = "none";
			}
			</script>

			<figcaption>
				Current example terminal output (click for enlarged view)
			</figcaption>
		</figure>
	</div>

	<div class="frame-footer">																								<!-- ------------- filename (below) --------- -->
		The code file for this example is available <a href="https://github.com/rontarrant/gtkd_demos/blob/master/005_mouse/mouse_03_enter_leave.d" target="_blank">here</a>.
	</div>
</div>

<p>Today’s code also takes place in an unadorned <em>TestRigWindow</em>, not because <em>Button</em>s would confuse things, but because we only need a window to illustrate the <code class="language-plaintext highlighter-rouge">ENTER_NOTIFY</code> and <code class="language-plaintext highlighter-rouge">LEAVE_NOTIFY</code> events, what happens when the mouse pointer enters or leaves a designated area.</p>

<p>The example uses a <code class="language-plaintext highlighter-rouge">MainWindow</code> derivative, but it can be used with any object derived from a <code class="language-plaintext highlighter-rouge">Widget</code>, a <code class="language-plaintext highlighter-rouge">Button</code>, even a <code class="language-plaintext highlighter-rouge">MenuItem</code>, or if a container of some kind. Pretty much anything you need to do with it.</p>

<p>And let’s have a look…</p>

<h2 id="constructor-changes">Constructor Changes</h2>

<div class="language-d highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">this</span><span class="p">()</span>
<span class="p">{</span>
	<span class="c1">// window</span>
	<span class="k">super</span><span class="p">(</span><span class="n">title</span><span class="p">);</span>
	<span class="n">addOnDestroy</span><span class="p">(</span><span class="k">delegate</span> <span class="kt">void</span><span class="p">(</span><span class="n">Widget</span> <span class="n">w</span><span class="p">)</span> <span class="p">{</span> <span class="n">quitApp</span><span class="p">();</span> <span class="p">}</span> <span class="p">);</span>
	
	<span class="c1">// make the window sensitive to mouse clicking (any button)</span>
	<span class="n">addOnEnterNotify</span><span class="p">(&amp;</span><span class="n">onEvent</span><span class="p">);</span>
	<span class="n">addOnLeaveNotify</span><span class="p">(&amp;</span><span class="n">onEvent</span><span class="p">);</span>
	
	<span class="c1">// Show the window and its contents...</span>
	<span class="n">showAll</span><span class="p">();</span>
	
<span class="p">}</span> <span class="c1">// this()</span>
</code></pre></div></div>

<p>At first glance, it looks like we’re setting up a signal chain like we did before, but these signals won’t be firing at the same time. As you might expect, one fires as the mouse enters the window, the other as it leaves.</p>

<p>And notice, too, that both signals are set up to trigger the same callback, <code class="language-plaintext highlighter-rouge">onEvent()</code>, so let’s have a look at that:</p>

<div class="language-d highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="kt">bool</span> <span class="n">onEvent</span><span class="p">(</span><span class="n">Event</span> <span class="n">event</span><span class="p">,</span> <span class="n">Widget</span> <span class="n">widget</span><span class="p">)</span>
<span class="p">{</span>
	<span class="kt">bool</span> <span class="n">value</span> <span class="p">=</span> <span class="kc">false</span><span class="p">;</span>
	<span class="nb">string</span> <span class="n">article</span><span class="p">;</span>
	
	<span class="k">if</span><span class="p">(</span><span class="n">event</span><span class="p">.</span><span class="n">type</span><span class="p">()</span> <span class="p">==</span> <span class="n">EventType</span><span class="p">.</span><span class="n">ENTER_NOTIFY</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">article</span> <span class="p">=</span> <span class="s">"an "</span><span class="p">;</span>
	<span class="p">}</span>
	<span class="k">else</span>
	<span class="p">{</span>
		<span class="n">article</span> <span class="p">=</span> <span class="s">"a "</span><span class="p">;</span>
	<span class="p">}</span>
	
	<span class="n">writeln</span><span class="p">(</span><span class="n">messageStart</span><span class="p">,</span> <span class="n">article</span><span class="p">,</span> <span class="n">event</span><span class="p">.</span><span class="n">type</span><span class="p">(),</span> <span class="s">" event."</span><span class="p">);</span>

	<span class="k">return</span><span class="p">(</span><span class="n">value</span><span class="p">);</span>
	
<span class="p">}</span> <span class="c1">// onEvent()</span>
</code></pre></div></div>

<p>Well, ain’t that fancy. This function even takes care of the grammar. The <code class="language-plaintext highlighter-rouge">messageStart</code>, defined at the top of the <code class="language-plaintext highlighter-rouge">TestRigWindow</code> class, looks like this:</p>

<div class="language-d highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">string</span> <span class="n">messageStart</span> <span class="p">=</span> <span class="s">"We've experienced "</span><span class="p">;</span>
</code></pre></div></div>

<p>And after <code class="language-plaintext highlighter-rouge">onEvent()</code>’s if’s, and’s and but’s, we get messages like:</p>

<p>We’ve experienced an <code class="language-plaintext highlighter-rouge">ENTER_NOTIFY</code> event.</p>

<p>or</p>

<p>We’ve experienced a <code class="language-plaintext highlighter-rouge">LEAVE_NOTIFY</code> event.</p>

<p>Okay, that’s all we need to look at here. Let’s move on.</p>

<h2 id="mouse-pointer-tracking">Mouse Pointer Tracking</h2>

<div class="screenshot-frame">
	<div class="frame-header">
		Results of this example:
	</div>
	<div class="frame-screenshot">
		<figure>
			<img id="img2" src="../images/screenshots/005_mouse/mouse_04.png" alt="Current example output" />		<!-- img# -->
			
			<!-- Modal for screenshot -->
			<div id="modal2" class="modal">																<!-- modal# -->
				<span class="close2">&times;</span>														<!-- close# -->
				<img class="modal-content" id="img22" />														<!-- img## -->
				<div id="caption"></div>
			</div>
			
			<script>
			// Get the modal
			var modal = document.getElementById("modal2");													// modal#
			
			// Get the image and insert it inside the modal - use its "alt" text as a caption
			var img = document.getElementById("img2");														// img#
			var modalImg = document.getElementById("img22");												// img##
			var captionText = document.getElementById("caption");

			img.onclick = function()
			{
			  modal.style.display = "block";
			  modalImg.src = this.src;
			  captionText.innerHTML = this.alt;
			}
			
			// Get the <span> element that closes the modal
			var span = document.getElementsByClassName("close2")[0];										// close#
			
			// When the user clicks on <span> (x), close the modal
			span.onclick = function()
			{ 
				modal.style.display = "none";
			}
			</script>
			<figcaption>
			Current example output
			</figcaption>
		</figure>
	</div>

	<div class="frame-terminal">
		<figure class="right">
			<img id="img3" src="../images/screenshots/005_mouse/mouse_04_term.png" alt="Current example terminal output" /> 		<!-- img#, filename -->

			<!-- Modal for terminal shot -->
			<div id="modal3" class="modal">																			<!-- modal# -->
				<span class="close3">&times;</span>																	<!-- close# -->
				<img class="modal-content" id="img33" />																	<!-- img## -->
				<div id="caption"></div>
			</div>
			
			<script>
			// Get the modal
			var modal = document.getElementById("modal3");																// modal#
			
			// Get the image and insert it inside the modal - use its "alt" text as a caption
			var img = document.getElementById("img3");																	// img#
			var modalImg = document.getElementById("img33");															// img##
			var captionText = document.getElementById("caption");

			img.onclick = function()
			{
			  modal.style.display = "block";
			  modalImg.src = this.src;
			  captionText.innerHTML = this.alt;
			}
			
			// Get the <span> element that closes the modal
			var span = document.getElementsByClassName("close3")[0];													// close#
			
			// When the user clicks on <span> (x), close the modal
			span.onclick = function()
			{ 
				modal.style.display = "none";
			}
			</script>

			<figcaption>
				Current example terminal output (click for enlarged view)
			</figcaption>
		</figure>
	</div>

	<div class="frame-footer">																							<!--------- filename (below) ------------>
		The code file for this example is available <a href="https://github.com/rontarrant/gtkd_demos/blob/master/005_mouse/mouse_04_tracker.d" target="_blank">here</a>.
	</div>
</div>

<p>In the constructor, we hook up the <code class="language-plaintext highlighter-rouge">MOTION_NOTIFY</code> signal by calling <code class="language-plaintext highlighter-rouge">addOnMotionNotify()</code>:</p>

<div class="language-d highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">this</span><span class="p">()</span>
<span class="p">{</span>
	<span class="k">super</span><span class="p">(</span><span class="n">title</span><span class="p">);</span>
	<span class="n">addOnDestroy</span><span class="p">(</span><span class="k">delegate</span> <span class="kt">void</span><span class="p">(</span><span class="n">Widget</span> <span class="n">w</span><span class="p">)</span> <span class="p">{</span> <span class="n">quitApp</span><span class="p">();</span> <span class="p">}</span> <span class="p">);</span>
	
	<span class="c1">// make the callback sensitive to mouse movement</span>
	<span class="n">addOnMotionNotify</span><span class="p">(&amp;</span><span class="n">onMotion</span><span class="p">);</span>
	
	<span class="n">showAll</span><span class="p">();</span>
	
<span class="p">}</span> <span class="c1">// this()</span>
</code></pre></div></div>

<p>And the <code class="language-plaintext highlighter-rouge">onMotion()</code> callback does the tracking:</p>

<div class="language-d highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="kt">bool</span> <span class="n">onMotion</span><span class="p">(</span><span class="n">Event</span> <span class="n">event</span><span class="p">,</span> <span class="n">Widget</span> <span class="n">widget</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">if</span><span class="p">(</span><span class="n">event</span><span class="p">.</span><span class="n">type</span> <span class="p">==</span> <span class="n">EventType</span><span class="p">.</span><span class="n">MOTION_NOTIFY</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">writeln</span><span class="p">(</span><span class="s">"x = "</span><span class="p">,</span> <span class="n">event</span><span class="p">.</span><span class="n">motion</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="s">" y = "</span><span class="p">,</span> <span class="n">event</span><span class="p">.</span><span class="n">motion</span><span class="p">.</span><span class="n">y</span><span class="p">);</span>
	<span class="p">}</span>

	<span class="k">return</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
	
<span class="p">}</span> <span class="c1">// onMotion()</span>
</code></pre></div></div>

<p>Yup, you’ve got to dig down a little to find those coordinates. As you may imagine, this would give you raw data for drawing with the mouse or perhaps for pulling a noodle from one node to another.</p>

<h2 id="conclusion">Conclusion</h2>

<p>And there we have it, two more examples of harnessing Events to do our bidding.</p>

<p>Until next time…</p>

<div class="blog-nav">
	<div style="float: left;">
		<a href="./0014-reacting-to-mouse-events.html">Previous: Mouse Events</a>
	</div>
	<div style="float: right;">
		<a href="./0016-scroll-pointer-all.html">Next: Scrollwheel, etc.</a>
	</div>
</div>
<p>
	<h3></h3>
<div class="inpage-frame">
	<a href="https://github.com/sponsors/rontarrant">
		<BR>
		<BR>
		<B>Is this article useful? Educational? Entertaining, perhaps?</B>
		<BR>
		<figure class="left">
			<img src="../images/favorite_32.png" alt="Sponsorship heart" style="width: 32px; height: 32px;">
		</figure>
		You're free to accept or decline this invitation to become our newest sponsor.
	</a>
</div>
	<h4 class="comment-blurb"><B>Comments? Questions? Observations?</B></h4>
	<p>
		Did we miss a tidbit of information that would make this post even more informative? Let's talk about it in the comments.
	</p>
	<script src="https://utteranc.es/client.js"
		repo="rontarrant"
		issue-term="pathname"
		theme="github-light"
		crossorigin="anonymous"
		async>
	</script>
	<ul>
		<li> come on over to the <a href="https://forum.dlang.org/">D Language Forum</a> and look for one of the <i>gtkDcoding</i> announcement posts, </li>
		<li> drop by <a href="https://forum.gtkd.org/">the <i>GtkD Forum</i></a>,</li>
		<li> follow the link below to email me, or</li>
		<li> go to the	<a href="https://www.facebook.com">gtkDcoding Facebook page.</a></li>
	</ul>
</p>
<p> You can also subscribe <a href="/feed.xml">via RSS</a> so you won't miss anything. Thank you very much for dropping by.</p>
<p>&copy; Copyright 2025 Ron Tarrant </p>
</div>

	<a class="u-url" href="./0015-enter-leave.html" hidden></a>
</article>

      </div>
    </main><footer class="site-footer h-card">
  <data class="u-url" href="/"></data>

  <div class="wrapper">

    <h2 class="footer-heading">gtkDcoding</h2>

    <div class="footer-col-wrapper">
      <div class="footer-col footer-col-1">
        <ul class="contact-list">
          <li class="p-name">Ron Tarrant</li><li><a class="u-email" href="mailto:gtkDcoding@gmail.com">gtkDcoding@gmail.com</a></li></ul>
      </div>

      <div class="footer-col footer-col-2"><ul class="social-media-list"><li><a href="https://github.com/rontarrant"><svg class="svg-icon"><use xlink:href="../assets/minima-social-icons.svg#github"></use></svg> <span class="username">rontarrant</span></a></li></ul>
</div>

      <div class="footer-col footer-col-3">
        <p>Simple examples of how to use GtkD to build GUI applications.</p>
      </div>
    </div>

  </div>

</footer>
</body>

</html>
